﻿using System.Linq ;
using System.Windows.Interactivity ;
using System.ComponentModel ;
using System.Windows.Controls ;
using System.ServiceModel.DomainServices.Client.ApplicationServices ;
using System ;
using System.Collections.ObjectModel ;

namespace OpenLightGroup.Common.Interactivity
    {
        /// <summary>
        /// Action to redirect a users that is not in one of the allowed roles.
        /// </summary>
        [Description( "Causes a redirect to occur if the current user is not in one of the allowed roles." )]
        public class RoleBasedRedirectAction
        : TriggerAction<Page>
            {
                /// <summary>
                /// Handles wiring up an event handler to the LoggedOut event if the InvokeOnLoggedOut property is set to true.
                /// </summary>
                public RoleBasedRedirectAction ( )
                    {
                        this.AllowedRoles = new Collection<string>( ) ;

                        if (DesignTimeHelper.IsRuntime)
                        {
                            if ( this.InvokeOnLoggedOut )
                            {

                                WebContextBase.Current.Authentication.LoggedOut +=
                                new EventHandler<AuthenticationEventArgs>( (sender, e) => this.Invoke( sender ) ) ;

                            }
                        }
                    }


                /// <summary>
                /// Uri to redirect to if the user is not a member of a role in the AllowedRoles list.
                /// </summary>
                [Category( "Redirect Settings" )]
                public Uri NavigationUri { get ; set ; }

                /// <summary>
                /// List of allowed roles. Members of these roles will NOT be redirected.
                /// </summary>
                [Category( "Redirect Settings" )]
                [Description( "A redirect will occur if the current user is NOT a member of one or more of these roles." )]
                public Collection<string> AllowedRoles { get ; private set ; }

                /// <summary>
                /// This option will override the AllowedRoles security check, and redirect regardless of the current users roles.
                /// </summary>
                [Category( "Redirect Settings" )]
                [Description( "This option will override the AllowedRoles security check, and redirect regardless of the current users roles." )]
                public bool AlwaysRedirect { get ; set ; }

                /// <summary>
                /// If true this action will run when the current user logs out. Uses the WebContextBase.Current.Authentiction.LoggedOut event.
                /// </summary>
                [Category( "Redirect Settings" )]
                [Description( "If true this action will run when the current user logs out. Uses the WebContextBase.Current.Authentiction.LoggedOut event." )]
                public bool InvokeOnLoggedOut { get ; set ; }

                /// <summary>
                /// Method that handles the redirect logic and execution.
                /// </summary>
                /// <param name="parameter">Not used, but is required by the base class.</param>
                protected override void Invoke ( object parameter )
                    {

                        if (DesignTimeHelper.IsRuntime)
                        {

                            if ( this.AlwaysRedirect
                                 || this.AllowedRoles.Where( r => WebContextBase.Current.Authentication.User.IsInRole( r ) ).Count( ) == 0 )
                            {
                              
                                this.AssociatedObject.NavigationService.Navigate( this.NavigationUri ) ;

                            }

                        }

                    }

            }
    }